﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace ToDictionary
{
    public class ConfigurationParser
    {
        public IDictionary<string, string> ToDictionary(string configString)
        {
            var configuration = new Configuration( configString );
            var settings = SplitIntoSettings( configuration );
            var tuples = SplitIntoParameterValueTuple( settings );
            return CreateDictionary( tuples );
        }

        internal IEnumerable<Setting> SplitIntoSettings( Configuration configuration )
        {
            var settings = new Collection<Setting>();
            if( string.IsNullOrEmpty( configuration.Value ) )
            {
                return settings;
            }

            var settingStrings = configuration.Value.Split( new[]{';'}, StringSplitOptions.RemoveEmptyEntries );
            foreach( var settingString in settingStrings )
            {
                settings.Add( new Setting( settingString ) );
            }
            return settings;
        }

        internal IEnumerable<Tuple<string, string>> SplitIntoParameterValueTuple( IEnumerable<Setting> settings )
        {
            var tuples = new Collection<Tuple<string, string>>();
            foreach( var setting in settings )
            {
                if( setting.Value == "" )
                {
                    continue;
                }
                tuples.Add( ParseSetting( setting ) );
            }
            return tuples;
        }

        internal IDictionary<string, string> CreateDictionary( IEnumerable<Tuple<string, string>> parameterValueTuples )
        {
            return parameterValueTuples.ToDictionary( parameterValueTuple => parameterValueTuple.Item1, parameterValueTuple => parameterValueTuple.Item2 );
        }

        private static Tuple<string, string> ParseSetting( Setting setting )
        {
            var firstEqualsIndex = setting.Value.IndexOf( '=' );
            if( firstEqualsIndex == -1 )
            {
                return new Tuple<string, string>( setting.Value, string.Empty );
            }
            if( firstEqualsIndex == 0 )
            {
                throw new ArgumentException( string.Format( "No key given: {0}", setting.Value ) );
            }
            var key = setting.Value.Substring( 0, firstEqualsIndex ).Trim();
            var value = setting.Value.Substring( firstEqualsIndex + 1 );
            return new Tuple<string, string>( key, value );
        }
    }
}